/*
 * arch/ckcore/ck6408evb/timer.c --- timer handles
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2004, Kang Sun (sunk@vlsi.zju.edu.cn)
 * Copyright (C) 2004, Li Chunqiang (chunqiang_li@c-sky.com)
 * Copyright (C) 2009, Hu Junshan (junshan_hu@c-sky.com)
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/param.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/rtc.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/ckcore.h>
#include <mach/gx6002_timer.h>
#include <asm/delay.h>

extern irqreturn_t ckcore_timer_interrupt(int irq, void *dummy);

static struct irqaction gx6002_timer_irq = {
        .name           = "GX6002 Timer Tick",
        .flags          = IRQF_DISABLED,
        .handler        = ckcore_timer_interrupt,
};

/*
 *  Clears the interrupt from timer1.
 */
void gx6002_tick(void)
{
unsigned index;
	unsigned int i;
	*(volatile unsigned int *)BASE_TIME1 &= ~(0x1<<24);	
	i = *(volatile unsigned int *)0xe0030000;
(*(volatile unsigned int *)(0xE00f0014))=(1<<23)|(1<<22)|(1<<24);
__asm__ __volatile__("DOZE");
for(index =0;index<500;index++);
}

/*
 * Initial the time controller of c-sky. We use timer1 to system time.
 */
void __init gx6002_timer_init(irq_handler_t handler)
{
	volatile unsigned int  *timerp;
	unsigned val,feq;

	timerp = (volatile unsigned int *)(BASE_TIME1);
	
	val = CONTER_MAX_VALUE -(((TIME_DURATION_10MS)*(1))-1);
	feq = ((SYSBOOT_108MHZ)/(CLOCK_FREQ_1MHZ)) - 1;
	
	timerp[1] = feq;
	timerp[2] = val;
	timerp[0] = (1<<0)|(1<<1);

	/*
	 * set interrupt controller for timer
	 * the number of timer interrupt is 8
	 */
	setup_irq(1, &gx6002_timer_irq);
}


unsigned long gx6002_timer_offset(void)
{

	volatile unsigned int  *timerp;

        timerp = (volatile unsigned int *)(BASE_TIME1);


	volatile unsigned long usec;
	volatile unsigned long t;
	t =  timerp[3];
	t = t&(0xffffff);
//	usec = ((t - 0xFFD8EF)/(0xFFFFFF - 0xFFD8EF))/10000;
	usec = (t - 0xFFD8EF);
	return usec;
}

/*
 *  set or get the real time clock. But now, we don't support.
 */
int gx6002_hwclk(int set, struct rtc_time *t)
{
	t->tm_year = 1980;
	t->tm_mon  = 1;
	t->tm_mday = 1;
	t->tm_hour = 0;
	t->tm_min  = 0;
	t->tm_sec  = 0;	

	return 0;
}

